package com.atguigu.juc.pool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingQueueTest {

    public static void putElementTest(String[] args) throws InterruptedException {

        // 0、设置阻塞队列的容量
        int capacity = 3;

        // 1、创建阻塞队列对象
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(capacity);

        // 2、存入三个元素
        blockingQueue.put("element01");
        System.out.println("已存入第一个元素");

        blockingQueue.put("element02");
        System.out.println("已存入第二个元素");

        blockingQueue.put("element03");
        System.out.println("已存入第三个元素");

        blockingQueue.put("element04");
        System.out.println("已存入第四个元素");

    }

    public static void takeElementTest(String[] args) throws InterruptedException {
        // 1、指定阻塞队列的容量
        int capacity = 3;

        // 2、创建阻塞队列对象
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(capacity);

        // 3、测试从空队列中获取元素时会被阻塞（需要等待）
        System.out.println("即将执行take()方法：");
        String element = blockingQueue.take();
        System.out.println("element = " + element);
    }

    public static void putElementAndTakeTest(String[] args) {
        // 1、指定阻塞队列的容量
        int capacity = 3;

        // 2、创建阻塞队列的对象
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(capacity);

        // 3、在 A 线程中测试存入元素
        new Thread(() -> {
            try {
                blockingQueue.put("element01");
                System.out.println("已存入第一个元素 threadName = " + Thread.currentThread().getName());

                blockingQueue.put("element02");
                System.out.println("已存入第二个元素 threadName = " + Thread.currentThread().getName());

                blockingQueue.put("element03");
                System.out.println("已存入第三个元素 threadName = " + Thread.currentThread().getName());

                blockingQueue.put("element04");
                System.out.println("已存入第四个元素 threadName = " + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-a").start();

        // 4、在 B 线程中从阻塞队列取出元素
        new Thread(
            () -> {
                try {
                    TimeUnit.SECONDS.sleep(8);
                    System.out.println(Thread.currentThread().getName() + " 线程取走一个元素。");
                    blockingQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "thread-b"
        ).start();
    }

    public static void takeElementAndPutTest(String[] args) {
        // 1、指定阻塞队列的容量
        int capacity = 3;

        // 2、创建阻塞队列的对象
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(capacity);

        // 3、在 A 线程中从空队列获取元素
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + " 即将从队列取出元素：");
                String element = blockingQueue.take();
                System.out.println("element = " + element);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-a").start();

        // 4、在 B 线程中把元素放入队列
        new Thread(()->{

            try {
                TimeUnit.SECONDS.sleep(8);

                System.out.println(Thread.currentThread().getName() + " 即将把元素放入队列：");
                blockingQueue.put("EEEEEEEEEE");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "thread-b").start();
    }

}
